home *** CD-ROM | disk | FTP | other *** search
- /*
- * SFtoSpr - Star Fighter 3000 graphics converter
- * Savebox for sprites extracted from MapTiles/Planets
- * Copyright (C) 2000 Chris Bazley
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public Licence as published by
- * the Free Software Foundation; either version 2 of the Licence, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public Licence for more details.
- *
- * You should have received a copy of the GNU General Public Licence
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- /* ANSI library files */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdbool.h>
-
- /* RISC OS library files */
- #include "wimp.h"
- #include "toolbox.h"
- #include "event.h"
- #include "wimplib.h"
- #include "saveas.h"
- #include "window.h"
- #include "gadgets.h"
- #include "flex.h"
-
- /* My library files */
- #include "err.h"
- #include "msgtrans.h"
- #include "hourglass.h"
- #include "Macros.h"
- #include "ViewsMenu.h"
- #include "Loader.h"
- #include "SFformats.h"
- #include "SprFormats.h"
- #include "NoBudge.h"
- #include "TboxBugs.h"
- #include "FilePerc.h"
-
- /* Local headers */
- #include "Utils.h"
- #include "SFgfxconv.h"
- #include "Main.h"
- #include "SaveSprites.h"
-
- /* Gadget IDs */
- #define TEXTOSPR_SAVEANIMS 0x00
-
- typedef struct _SaveSpritesData
- {
- ObjectId saveas_id;
- ObjectId window_id;
- char *reset_file_name;
- spriteareaheader *sprite_area; /* flex block */
- SF_MapTilesSetHdr *animations; /* copy of original tiles header */
- int reset_save_anims;
- bool no_budge;
- } SaveSpritesData;
-
- /* -----------------------------------------------------------------------
- * Function prototypes
- */
-
- static ToolboxEventHandler _SaveSprites_savehandler, _SaveSprites_ramhandler, _SaveSprites_savecompleted, _SaveSprites_deletedhandler, _SaveSprites_buttonshandler;
-
- /* -----------------------------------------------------------------------
- * Public functions
- */
-
- ObjectId SaveSprites_create(char *savepath, int data_saved, spriteareaheader **sprite_area, SF_MapTilesSetHdr **animations)
- {
- /* If animations == NULL then we are saving planet graphics.
- Must COPY animations to retain data (will be flex_free'd)
- Must either RE-ANCHOR sprite_area or flex_free() it
- (will only be flex_free'd if we return NULL_ObjectId) */
- SaveSpritesData *newblk;
- char *views_path, *list_tok, *obj_templ;
-
- /* Grab memory */
- newblk = malloc(sizeof(SaveSpritesData));
- if(newblk == NULL)
- MG_RETV("NoMem", NULL_ObjectId) /* failure */
-
- newblk->no_budge = false; /* we aren't preventing flex budging */
- newblk->reset_file_name = NULL;
- newblk->animations = NULL;
-
- if(animations != NULL) {
- /* Copy header of tiles set to preserve animations */
- newblk->animations = malloc(sizeof(SF_MapTilesSetHdr));
- if(newblk->animations == NULL) {
- MG("NoMem");
- goto errexit_free;
- }
- nobudge_register(256);
- memcpy(newblk->animations, *animations, sizeof(SF_MapTilesSetHdr));
- nobudge_deregister();
-
- list_tok = "TexSprList";
- obj_templ = "TexToSpr";
-
- } else {
- list_tok = "PlaSprList";
- obj_templ = "PlaToSpr";
- }
-
- /* Create object */
- if(E(toolbox_create_object(0, obj_templ, &newblk->saveas_id)))
- goto errexit_free;
- if(E(saveas_get_window_id(0, newblk->saveas_id, &newblk->window_id)))
- goto errexit_delete;
-
- /* Store default settings */
- if((newblk->reset_file_name = copystring(savepath)) == NULL)
- goto errexit_delete;
- if(animations != NULL) {
- if(E(optionbutton_get_state(0, newblk->window_id, TEXTOSPR_SAVEANIMS, &newblk->reset_save_anims)))
- goto errexit_delete;
- }
-
- /* Add entry to iconbar menu */
- if(data_saved)
- views_path = savepath; /* we have real filepath */
- else
- views_path = ""; /* dummy filepath */
- if(E(ViewsMenu_add(newblk->saveas_id, msgs_lookup_sub1(list_tok, tail(savepath, 3)), views_path)))
- goto errexit_delete;
-
- /* Set up window */
- if(E(saveas_set_file_name(0, newblk->saveas_id, savepath))
- || E(saveas_set_file_type(0, newblk->saveas_id, FILETYPE_SPRITE))
- || E(saveas_set_file_size(0, newblk->saveas_id, flex_size((flex_ptr)sprite_area)-4)))
- goto errexit_menuremove;
-
- /*
- Note the ObjectDeleted handler is registered AFTER anything that could cause an error and therefore premature deletion!
- */
- if(E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_SaveToFile, _SaveSprites_savehandler, newblk))
- || E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_FillBuffer, _SaveSprites_ramhandler, newblk))
- || E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_SaveCompleted, _SaveSprites_savecompleted, newblk))
- || E(event_register_toolbox_handler(newblk->saveas_id, SaveAs_DialogueCompleted, delete_object_handler, newblk))
- || E(event_register_toolbox_handler(newblk->window_id, ActionButton_Selected, _SaveSprites_buttonshandler, newblk))
- || E(event_register_toolbox_handler(newblk->saveas_id, Toolbox_ObjectDeleted, _SaveSprites_deletedhandler, newblk)))
- goto errexit_menuremove;
-
- flex_reanchor((flex_ptr)&newblk->sprite_area, (flex_ptr)sprite_area);
- return newblk->saveas_id; /* success */
-
- errexit_menuremove:
- RE(ViewsMenu_remove(newblk->saveas_id));
- errexit_delete:
- RE(toolbox_delete_object(0, newblk->saveas_id));
- errexit_free:
- free(newblk->reset_file_name);
- free(newblk->animations);
- free(newblk);
- return NULL_ObjectId; /* failure */
- }
-
- /* -----------------------------------------------------------------------
- * Private functions
- */
-
- /*
- * Toolbox event handlers
- */
-
- static int _SaveSprites_savehandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
- {
- SaveAsSaveToFileEvent *save_to_file_block = (SaveAsSaveToFileEvent *)event;
- SaveSpritesData *blk = (SaveSpritesData *)handle;
- unsigned int flags = 0;
-
- /* Save output spritefile (from Planets or MapTiles) */
- {
- _kernel_oserror *err = perc_operation(FILEPERC_OP_SAVE, save_to_file_block->filename, FILETYPE_SPRITE|(1u<<31), (flex_ptr)&blk->sprite_area);
- if(err != NULL) {
- err_report(err->errnum, msgs_lookup_sub1("SaveFail", err->errmess));
- goto exit;
- }
- }
-
- if(blk->animations != NULL) {
- /* Check whether we should save animations textfile too */
- int save_anims;
- if(E(optionbutton_get_state(0, blk->window_id, TEXTOSPR_SAVEANIMS, &save_anims)))
- goto exit;
-
- if(save_anims) {
- /* We can't transfer them direct to another app */
- if(!ViewsMenu_strcmp_nc(save_to_file_block->filename, "<Wimp$Scrap>")) {
- #ifndef OLD_SCL_STUBS
- char texfilename[strlen(save_to_file_block->filename) + 4 + 1];
- #else
- char *texfilename = malloc(strlen(save_to_file_block->filename) + 4 + 1);
- if(texfilename == NULL) {
- MG("NoMem");
- goto exit;
- }
- #endif
- sprintf(texfilename, "%s/ani", save_to_file_block->filename);
-
- _kernel_oserror *err = save_animsfile(texfilename, blk->animations);
- #ifdef OLD_SCL_STUBS
- free(texfilename);
- #endif
- if(err != NULL) {
- err_report(err->errnum, msgs_lookup_sub1("SaveFail", err->errmess));
- goto exit;
- }
- }
- }
- }
- flags = 1; /* success */
-
- exit:
- saveas_file_save_completed(flags, id_block->self_id, save_to_file_block->filename);
- return 1; /* claim event */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static int _SaveSprites_ramhandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
- {
- SaveAsFillBufferEvent *fill_buffer_event = (SaveAsFillBufferEvent *)event;
- SaveSpritesData *blk = (SaveSpritesData *)handle;
-
- if(blk->no_budge) {
- blk->no_budge = false;
- nobudge_deregister();
- }
-
- /* sprite file is sprite area without first word */
- int spritefile_size = flex_size((flex_ptr)&blk->sprite_area) - 4;
-
- int chunk_size;
- if(fill_buffer_event->no_bytes > spritefile_size)
- /* Already sent all data */
- chunk_size = 0;
- else {
- /* Calculate bytes still to send */
- int bytes_to_go = spritefile_size - fill_buffer_event->no_bytes;
- if(bytes_to_go > fill_buffer_event->size)
- /* Can't fit remaining, so just fill buffer */
- chunk_size = fill_buffer_event->size;
- else
- /* Send all of remaining data */
- chunk_size = bytes_to_go;
- }
- nobudge_register(1024);
- blk->no_budge = true;
- RE(saveas_buffer_filled(0, id_block->self_id, (void *)((int)blk->sprite_area + 4 + fill_buffer_event->no_bytes), chunk_size));
-
- return 1; /* claim event */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static int _SaveSprites_savecompleted(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
- {
- /* Save completed */
- SaveSpritesData *blk = (SaveSpritesData *)handle;
- if(blk->no_budge) {
- blk->no_budge = false;
- nobudge_deregister();
- }
- return 1; /* claim event */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static int _SaveSprites_buttonshandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
- {
- ActionButtonSelectedEvent *abse = (ActionButtonSelectedEvent *)event;
- SaveSpritesData *blk = (SaveSpritesData *)handle;
-
- if(!FLAG_SET(abse->hdr.flags, ActionButton_Selected_Adjust))
- return 0; /* not interested */
-
- switch(id_block->self_component) {
- case 0x82bc02: /* Cancel button */
- /* Reset dbox state */
- if(blk->reset_file_name != NULL)
- RE(saveas_set_file_name(0, blk->saveas_id, blk->reset_file_name));
-
- if(blk->animations != NULL)
- RE(optionbutton_set_state(0, id_block->self_id, TEXTOSPR_SAVEANIMS, blk->reset_save_anims));
- break;
-
- #ifndef SAVEAS_CRAP /* no point saving state if dbox closes anyway */
- case 0x82bc03: /* Save button */
- /* Record dbox state */
- if(blk->animations != NULL)
- RE(optionbutton_get_state(0, id_block->self_id, TEXTOSPR_SAVEANIMS, &blk->reset_save_anims));
-
- int len;
- E_RETV(saveas_get_file_name(0, blk->saveas_id, NULL, 0, &len), 1)
- free(blk->reset_file_name);
- blk->reset_file_name = malloc(len+1);
- if(blk->reset_file_name == NULL)
- err_complain(255, msgs_global("NoMem"));
- else
- RE(saveas_get_file_name(0, blk->saveas_id, blk->reset_file_name, len, NU break;
- #endif
-
- default:
- return 0; /* unknown component */
- }
-
- return 1; /* claim event */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static int _SaveSprites_deletedhandler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
- {
- SaveSpritesData *blk = (SaveSpritesData *)handle;
-
- if(blk->no_budge) {
- nobudge_deregister();
- }
- /* deregister handlers */
- RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_SaveToFile, _SaveSprites_savehandler, handle));
- RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_FillBuffer, _SaveSprites_ramhandler, handle));
- RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_SaveCompleted, _SaveSprites_savecompleted, handle));
- RE(event_deregister_toolbox_handler(id_block->self_id, SaveAs_DialogueCompleted, delete_object_handler, handle));
- RE(event_deregister_toolbox_handler(blk->window_id, ActionButton_Selected, _SaveSprites_buttonshandler, handle));
- RE(event_deregister_toolbox_handler(id_block->self_id, Toolbox_ObjectDeleted, _SaveSprites_deletedhandler, handle));
-
- /* Remove from iconbar menu */
- RE(ViewsMenu_remove(id_block->self_id));
-
- /* free memory */
- flex_free((flex_ptr)&blk->sprite_area);
- free(blk->reset_file_name);
- free(blk->animations);
- free(blk);
-
- if(last_savebox == id_block->self_id)
- last_savebox = NULL_ObjectId;
-
- return 1; /* claim event */
- }
-